# -*- coding: utf-8 -*-
"""
Src类, 源的计算与能量方程中的参数计算。
"""
# third party library
import numpy as np

# private library
from utils.constant import *
from algorithm.source_terms.flow_patterns.source_base import BaseSource
from algorithm.source_terms.flow_patterns.source_stratifiedflow import StratifiedFlowCalculator
from algorithm.source_terms.flow_patterns.source_annularflow import AnnularFlowCalculator
from algorithm.source_terms.flow_patterns.source_bubblyflow import BubblyFlowCalculator
from algorithm.source_terms.flow_patterns.source_slugflow import SlugFlowCalculator
from algorithm.source_terms.input_adapter import InputAdapter
from algorithm.source_terms.phase_transition.phase_transition import PhaseTransition
from utils.crdlog import log

class SourceInterface:
    """
    源项接口
    """
    def __init__(self):
        # 夹带率初始化
        self.entrainment_rate_segment_previous_time_step = None

    def _input_adapter(self, params: dict):
        """ 标准化输入适配器
        
        Args:
            params: dict 输入参数
            
        Returns:
            standard_input: dict 标准化输入
        """
        input_adapter = InputAdapter(params)
        self.standard_input = input_adapter.get_standard_input()
        return self.standard_input    

    def _apply_flow_pattern(self, standard_input: dict, flow_pattern_type: np.ndarray):
        """ 根据流型类型选择对应的源项计算方法
        
        Args:
            standard_input: dict 标准化输入
            flow_pattern_type: np.ndarray 流型类型
            
        Returns:
            source_calculator: np.ndarray 源项计算器
        """
        # if flow_pattern_type == FlowPatternID.StratifiedFlow.value:
        #     self.source_calculator = StratifiedFlowCalculator(standard_input)
        # elif flow_pattern_type == FlowPatternID.AnnularFlow.value:
        #     self.source_calculator = AnnularFlowCalculator(standard_input)
        # elif flow_pattern_type == FlowPatternID.SlugFlow.value:
        #     self.source_calculator = SlugFlowCalculator(standard_input)
        # elif flow_pattern_type == FlowPatternID.BubbleFlow.value:
        #     self.source_calculator = BubblyFlowCalculator(standard_input)
        self.source_calculator = StratifiedFlowCalculator(standard_input)
        return self.source_calculator

    def cal_friction_force(self, source_calculator):
        """ 计算摩擦力 """
        self.gas_wall_friction_force = source_calculator.cal_gas_wall_friction_force()
        self.liquid_wall_friction_force = source_calculator.cal_liquid_wall_friction_force()
        self.gas_liquid_friction_force = source_calculator.cal_gas_liquid_interface_friction_force()
        
    def get_friction_force(self):
        """ 获取摩擦力 """
        return self.gas_wall_friction_force, self.liquid_wall_friction_force, self.gas_liquid_friction_force

    def cal_phase_transition_terms(self):
        """ 计算相变项 """
        if self.entrainment_rate_segment_previous_time_step is None:
            self.entrainment_rate_segment_previous_time_step = np.zeros(self.standard_input['V_g_segment'].shape)
        phase_transition = PhaseTransition(self.standard_input, self.entrainment_rate_segment_previous_time_step)
        (self.liquid_vapour_mass_transfer_rate,
         self.V_i_segment,
         self.transition_velocity_from_liquid_film,
         self.transition_velocity_from_droplet,
         self.entrainment_rate_segment,
         self.liquid_to_droplet_mass_transfer_rate,
         self.droplet_to_liquid_mass_transfer_rate,
         self.droplet_velocity) = phase_transition.cal_phase_transition_source()
        
        # 夹带率计算完成之后利用当前时间步的夹带率更新前一个时间步的夹带率
        self.entrainment_rate_segment_previous_time_step = np.copy(self.entrainment_rate_segment)  

    def get_phase_transition_terms(self):
        """ 获取相变项 """
        return (self.liquid_vapour_mass_transfer_rate,
                self.V_i_segment,
                self.transition_velocity_from_liquid_film,
                self.transition_velocity_from_droplet,
                self.liquid_to_droplet_mass_transfer_rate,
                self.droplet_to_liquid_mass_transfer_rate,
                self.droplet_velocity)

